package com.example.socket.filter.session;

import com.example.socket.core.Request;
import com.example.socket.core.Session;

import java.util.Collection;

/**
 * 会话管理器接口
 */
public interface SessionManager {

    /**
     * 获取推送代理
     * @param clz 代理的推送接口
     * @param sessions SESSION
     * @return
     */
    <T> T getPushProxy(Class<T> clz, Session[] sessions);

    <T> T getPushProxy(Class<T> clz, Session session);

    /**
     * 获取推送代理
     * @param clz 代理的推送接口
     * @param ids
     * @return
     */
    <T> T getPushProxy(Class<T> clz, Object ids);

    /**
     * 获取推送代理
     * @param clz 代理的推送接口
     * @param ids
     * @return
     */
    <T> T getPushProxy(Class<T> clz, Object[] ids);

    /**
     * 获取推送代理
     * @param clz 代理的推送接口
     * @return
     */
    <T> T getPushAllProxy(Class<T> clz);

    // ----

    /**
     * 异步向指定目标发送请求
     * @param request
     * @param ids
     */
    void send(Request<?> request, Object... ids);

    /**
     * 异步向指定目标发送请求
     * @param request
     * @param sessions
     */
    void send(Request<?> request, Session[] sessions);

    /**
     * 异步向所有已认证会话发送请求
     * @param request
     */
    void sendAllIdentified(Request<?> request);

    /**
     * 检查指定用户是否在线
     * @param ids 用户标识
     * @return
     */
    boolean isOnline(Object... ids);

    /**
     * 添加会话监听器，每一种事件类型的监听器只能添加一个
     * @param listener 监听器实例
     * @throws IllegalStateException 重复添加同一类型的监听器时抛出
     */
    void addListener(SessionListener listener);

    // ---- SESSION 管理 ----

    /**
     * 踢指定的用户下线
     * @param cause 原因标识{@link SessionEventCause}
     * @param ids 被踢下线的用户标识
     */
    Collection<?> kick(int cause, Object... ids);

    /**
     * 踢指定的用户下线
     * @param cause 原因标识{@link SessionEventCause}
     * @param session 被踢下线的session
     * @return
     */
    void kick(int cause, Session session);

    /**
     * 将全部的在线用户踢下线
     * @param cause 原因标识{@link SessionEventCause}
     */
    Collection<?> kickAll(int cause);

    /**
     * 获取全部的在线用户标识
     * @return
     */
    Collection<?> getOnlineIdentities();

    /**
     * 获取全部的在线用户SESSION
     * @return
     */
    Collection<Session> getOnlineSessions();

    /**
     * 统计当前的会话数量
     * @param includeAnonymous 是否包含匿名会话
     * @return
     */
    int count(boolean includeAnonymous);

    /**
     * 获取指定用户标识的会话对象
     * @param id 用户标识
     * @return 会返回null，被延时关闭的会话也会返回
     */
    Session getSession(Object id);

    /**
     * 替换会话
     * @param src 来源对象
     * @param dest 复制目的地
     */
    void replace(Session src, Session dest);

    /**
     * 设置会话身份
     * @param session 来源对象
     * @param id 玩家标识
     */
    void bind(Session session, Object id);

}
